home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Info-Mac 4
/
Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso
/
Development
/
General
/
DR1.#1 PPC C⁄C++ ƒ
/
C++ Runtime ƒ
/
New.cp
< prev
next >
Wrap
Text File
|
1993-12-06
|
6KB
|
214 lines
/************************************************************************/
/* Project...: Standard C++ Library */
/* Name......: New.cp */
/* Purpose...: standard C++ library */
/* Copyright.: ©Copyright 1993 by metrowerks inc. All rights reserved. */
/************************************************************************/
#include <new.h>
#include <Memory.h>
#define SIMPLENEW 0 // call NewPtr(...)/DisposPtr(...) if != 0
/* prototypes */
void _set_newpoolsize(size_t);
void _set_newnonptrmax(size_t);
char _prealloc_newpool(size_t);
void *__new_hdl(size_t size);
void __del_hdl(void *hdl);
static void (*new_handler)();
extern void (*set_new_handler (void (*new_new_handler) ())) ()
{
void (*old_new_handler)() = new_handler;
new_handler = new_new_handler;
return old_new_handler;
}
#if SIMPLENEW
/************************************************************************/
/* Purpose..: Allocate memory */
/* Input....: size of memory to allocate */
/* Return...: pointer to memory or 0L */
/************************************************************************/
void *operator new(size_t size)
{
void *ptr;
while((ptr=NewPtr(size))==NULL)
{
if(new_handler) new_handler(); else return(NULL);
}
return(ptr);
}
/************************************************************************/
/* Purpose..: Dispose memory */
/* Input....: pointer to memory or 0L (no action if 0L) */
/* Return...: --- */
/************************************************************************/
void operator delete(void *ptr)
{
if(ptr) DisposPtr((Ptr)ptr);
}
#else
typedef struct FreeMemList {
struct FreeMemList *next;
long size;
} FreeMemList;
static FreeMemList memlist; // dummy header block (always empty)
static size_t _newpoolsize = 0x00010000L; // number of bytes allocated for a new pool
static size_t _newnonptrmax = 0x00001000L; // any object bigger than this will call NewPtr(...) directly
/************************************************************************/
/* Purpose..: Set size of future allocation pools */
/* Input....: size of future allocation pools */
/* Return...: --- */
/************************************************************************/
void _set_newpoolsize(size_t size)
{
_newpoolsize=size;
}
/************************************************************************/
/* Purpose..: Set NewPtr(...) pointer threshold */
/* Input....: size of new threshold */
/* Return...: --- */
/************************************************************************/
void _set_newnonptrmax(size_t size)
{
_newnonptrmax=size;
}
/************************************************************************/
/* Purpose..: Preallocate an allocation pool */
/* Input....: size of pool to allocate */
/* Return...: 1: no error; 0: fail */
/************************************************************************/
char _prealloc_newpool(size_t size)
{
FreeMemList *list;
if((list=(FreeMemList *)NewPtr(size))==NULL) return 0;
list->next=memlist.next; list->size=size; memlist.next=list;
return 1;
}
/************************************************************************/
/* Purpose..: Allocate memory */
/* Input....: size of memory to allocate */
/* Return...: pointer to memory or 0L */
/************************************************************************/
void *operator new(size_t size)
{
Ptr ptr;
size=(size&0xFFFFFFFC)+8; // alloc *4 quantity plus 4 extra bytes for size
if(size>=_newnonptrmax)
{ // try to get pointer from OS
while(1)
{
if((ptr=NewPtr(size))!=NULL) { *(long *)ptr=-1L; return(ptr+4); }
if(new_handler) new_handler(); else return(NULL);
}
}
while(1)
{
FreeMemList *list,*prev;
for(prev=&memlist,list=prev->next; list; prev=list,list=list->next) if(size<=list->size)
{
alloc: if(list->size>=size+sizeof(FreeMemList))
{ // split this free block
list->size-=size; ptr=(Ptr)list+list->size;
*(long *)ptr=size; return(ptr+4);
}
// remove this block from list
prev->next=list->next; *(long *)list=list->size; return((Ptr)list+4);
}
// not enough free memory in memlist (try to allocate a new Ptr from OS
if((list=(FreeMemList *)NewPtr(_newpoolsize))==NULL)
{
if(new_handler) new_handler(); else return(NULL);
}
else
{
list->next=memlist.next; list->size=_newpoolsize;
memlist.next=list; prev=&memlist; goto alloc;
}
}
}
/************************************************************************/
/* Purpose..: Dispose memory */
/* Input....: pointer to memory or 0L (no action if 0L) */
/* Return...: --- */
/************************************************************************/
void operator delete(void *ptr)
{
if(ptr)
{
long size;
ptr=(Ptr)ptr-4; size=*(long *)ptr;
if(size!=-1L)
{
FreeMemList *list,*prev;
for(prev=&memlist,list=prev->next; list; prev=list,list=list->next)
{
if((Ptr)ptr+size==(Ptr)list)
{ // merge block in front of this list item
prev->next=list->next; size+=list->size; list=prev; continue;
}
if((Ptr)ptr==(Ptr)list+list->size)
{ // merge block at the end of this list item
prev->next=list->next; ptr=list; size+=list->size; list=prev; continue;
}
}
list=(FreeMemList *)ptr; list->next=memlist.next; list->size=size; memlist.next=list;
}
else DisposPtr((Ptr)ptr);
}
}
#endif
/************************************************************************/
/* Purpose..: Allocate memory (handle) */
/* Input....: size of memory to allocate */
/* Return...: handle to memory or 0L */
/************************************************************************/
void *__new_hdl(size_t size)
{
void *ptr;
while((ptr=NewHandle(size))==NULL)
{
if(new_handler) new_handler(); else return(NULL);
}
return(ptr);
}
/************************************************************************/
/* Purpose..: Dispose memory (handle) */
/* Input....: handle to memory or 0L (no action if 0L) */
/* Return...: --- */
/************************************************************************/
void __del_hdl(void *hdl)
{
if(hdl) DisposHandle((Handle)hdl);
}